#include "TcpManager.h"

#include <QFile>

TcpManager::TcpManager(QObject *parent)
    : QObject{parent}
{
    m_TcpServer = new QTcpServer(this);
    bool listenStatus = m_TcpServer->listen(QHostAddress("192.168.0.102"),12345);
    if(listenStatus)
    {
        qDebug() << "监听成功，服务器启动";
    } else {
        qDebug() << "监听失败，服务器未能启动";
        return;
    }
    connect(m_TcpServer, &QTcpServer::newConnection, this, &TcpManager::onNewConnection);
}

void TcpManager::onNewConnection()
{
    qDebug() << "检测到新的客户端连接请求";
    QTcpSocket *clientSocket = m_TcpServer->nextPendingConnection();
    m_TcpSockets[clientSocket->peerAddress().toString()] = clientSocket;
    qDebug() << "新客户端已连接，IP地址: " << clientSocket->peerAddress().toString();
    connect(clientSocket, &QTcpSocket::readyRead, this, [=]() {
        qDebug() << "客户端 " << clientSocket->peerAddress().toString() << " 有数据可读，调用 onReadyRead 函数";
        onReadyRead(clientSocket);
    });

    connect(clientSocket,&QTcpSocket::disconnected,this,&TcpManager::slot_DisConnected);
    connect(clientSocket, &QTcpSocket::disconnected, clientSocket, &QTcpSocket::deleteLater);
    NewClient clientStu;
    clientStu.ip = clientSocket->peerAddress().toString();
    qDebug() << "准备通知其他客户端新客户端 " << clientStu.ip << " 已连接";
    noticeNewClient(clientStu);
}

void TcpManager::slot_DisConnected(QTcpSocket *tcpSocket)
{
    if(m_TcpSockets.contains(tcpSocket->peerAddress().toString())) m_TcpSockets.remove(tcpSocket->peerAddress().toString());
}


void TcpManager::onReadyRead(QTcpSocket* tcpSocket)
{
    qDebug() << "开始处理客户端 " << tcpSocket->peerAddress().toString() << " 的数据读取";
    m_Buffer.append(tcpSocket->readAll());
    qDebug() << "已读取数据，当前缓冲区大小: " << m_Buffer.size();
    if(m_Buffer.size() < 8) {
        qDebug() << "缓冲区大小小于8字节，等待更多数据";
        return;
    }

    Stu_Head headData;
    memcpy(&headData,m_Buffer.data(),8);
    qDebug() << "接收到头部数据，数据大小: " << headData.dataSize << "，信息类型: " << headData.infoType;

    if(m_Buffer.size() < headData.dataSize) {
        qDebug() << "缓冲区大小小于预期数据大小，等待更多数据";
        return;
    }
    QByteArray data = m_Buffer.mid(0,headData.dataSize);
    m_Buffer.remove(0,headData.dataSize);
    qDebug() << "提取数据，剩余缓冲区大小: " << m_Buffer.size();
    qDebug() << "开始处理数据，调用 processData 函数";
    processData(data,headData.infoType);
}

void TcpManager::processData(QByteArray &msgData, int type)
{
    qDebug() << "开始处理数据，消息类型: " << type;
    QDataStream stream(msgData);
    stream.setByteOrder(QDataStream::LittleEndian);
    switch (type)
    {
    case FilePacketType:
    {
        qDebug() << "消息类型为文件数据包，开始解析";
        FilePacket data;
        stream >> data;
        qDebug() << "文件数据包解析完成";
        break;
    }
    case MessagePacketType:
    {
        qDebug() << "消息类型为消息数据包，开始解析";
        MessagePacket data;
        stream >> data;
        if(m_TcpSockets.contains(data.targetAddress))
        {
            m_TcpSockets[data.targetAddress]->write(msgData);
            qWarning() << "向" << data.targetAddress << "发送文字消息";
        }

        qDebug() << "消息数据包解析完成";
        break;
    }
    default:
        qWarning() << "未知消息类型: " << type;
        break;
    }
}

void TcpManager::noticeNewClient(NewClient &newClient)
{
    qDebug() << "开始通知其他客户端新客户端 " << newClient.ip << " 已连接";
    for(auto it = m_TcpSockets.begin();it != m_TcpSockets.end();it++)
    {
        if(it.key() == newClient.ip) {
            qDebug() << "跳过新客户端自身，IP地址: " << newClient.ip;
            continue;
        }

        NewClient info = newClient;
        QByteArray tempBuffer;
        QDataStream tempStream(&tempBuffer,QIODevice::WriteOnly);
        tempStream.setByteOrder(QDataStream::LittleEndian);
        tempStream << info;

        info.dataSize = tempBuffer.size();

        QByteArray buffer;
        QDataStream stream(&buffer,QIODevice::WriteOnly);
        stream.setByteOrder(QDataStream::LittleEndian);
        stream << info;

        qDebug() << "向客户端 " << it.key() << " 发送新客户端连接通知";
        qWarning() << buffer.toHex();
        m_TcpSockets[it.key()]->write(buffer);
        m_TcpSockets[it.key()]->flush();

        NewClient stuClient;
        stuClient.ip = it.key();
        qDebug() << "通知新客户端 " << newClient.ip << " 关于客户端 " << stuClient.ip << " 的信息";
        cogradientClinet(newClient.ip,stuClient);
    }
    qDebug() << "新客户端连接通知完成";
}

void TcpManager::cogradientClinet(QString targetIP, NewClient &newClient)
{
    if(!m_TcpSockets.contains(targetIP)) {
        qDebug() << "目标客户端 " << targetIP << " 不存在，跳过";
        return;
    }
    NewClient info = newClient;
    QByteArray tempBuffer;
    QDataStream tempStream(&tempBuffer,QIODevice::WriteOnly);
    tempStream.setByteOrder(QDataStream::LittleEndian);
    tempStream << info;

    info.dataSize = tempBuffer.size();

    QByteArray buffer;
    QDataStream stream(&buffer,QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::LittleEndian);
    stream << info;

    qDebug() << "向目标客户端 " << targetIP << " 发送客户端 " << newClient.ip << " 的信息";
    qWarning() << buffer.toHex();
    int sendSize = m_TcpSockets[targetIP]->write(buffer);
    qWarning() << info.dataSize;
    qWarning() << "发送了" << sendSize << "字节";
    m_TcpSockets[targetIP]->flush();
    qDebug() << "信息发送完成";
}

